<template>
  <div class="app-container">
    <el-form ref="search" :model="searchParams" label-width="140px" inline>
      <el-form-item label="组件名称" prop="chineseDesc">
        <el-input v-model="searchParams.chineseDesc" style="width: 240px" />
      </el-form-item>
      <el-form-item label="组件标签" prop="label">
        <el-input v-model="searchParams.label" style="width: 240px" />
      </el-form-item>
      <el-form-item label="组件类别" prop="componentForm">
        <el-select v-model="searchParams.componentForm" clearable style="width: 240px">
          <el-option v-for="dict in componentFormOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue"/>
        </el-select>
      </el-form-item>
      <br>
      <el-form-item label="前端值类型" prop="valueType">
        <el-select v-model="searchParams.valueType" clearable style="width: 240px">
          <el-option v-for="dict in valueTypeOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue"/>
        </el-select>
      </el-form-item>
      <el-form-item label="是否低代码组件" prop="isLowCode">
            <el-radio-group v-model="searchParams.isLowCode">
              <el-radio v-for="dict in isEnableOptions" :key="dict.dictValue" :label="dict.dictValue">{{ dict.dictLabel }}</el-radio>
            </el-radio-group>
      </el-form-item>
      <el-form-item label="是否零代码组件" prop="isZeroCode">
            <el-radio-group v-model="searchParams.isZeroCode">
              <el-radio v-for="dict in isEnableOptions" :key="dict.dictValue" :label="dict.dictValue">{{ dict.dictLabel }}</el-radio>
            </el-radio-group>
      </el-form-item>
      <el-form-item>
        <search-button type="primary" @click="getCompList">查询</search-button>
        <reset-button type="default" @click="reset">重置</reset-button>
      </el-form-item>
    </el-form>
    <div style="margin-bottom: 8px">
      <add-button type="primary" @click="handleAddComp">新增</add-button>
      <delete-button text="批量删除" :disabled="!componentIds" @click="handleBatchDelete" />
      <import-button @click="handleImport" />
      <el-button type="warning" icon="Download" size="default" @click="handleExport">导出</el-button>
    </div>

    <el-table :data="compList" :loading="loading" stripe @selection-change="handleSelectionChange">
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="组件标识" prop="componentId" align="center" width="280px" />
      <el-table-column label="组件名称" prop="chineseDesc" align="center" min-width="160px" />
      <el-table-column label="组件标签" prop="label" align="center" min-width="160px" />
      <el-table-column label="组件类别" prop="componentForm" align="center">
        <template #default="scope">
          {{ selectDictLabel(componentFormOptions, scope.row.componentForm) }}
        </template>
      </el-table-column>
      <el-table-column label="前端值类型" prop="valueType" align="center" width="120px" />
      <el-table-column label="版本号" prop="version" align="center">
        <template #default="scope">
          <el-tag type="success">v{{ scope.row.version }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="创建者" prop="createBy" align="center" width="120" />
      <el-table-column label="创建时间" prop="createTime" align="center" width="160" />
      <el-table-column label="更新者" prop="updateBy" align="center" width="120" />
      <el-table-column label="更新时间" prop="updateTime" align="center" width="160" />
      <el-table-column label="操作" min-width="240px" align="center" fixed="right">
        <template #default="{ row }">
          <text-detail-button text="查看组件Json" @click="openJson(row)" />
          <text-edit-button @click="handleUpdate(row)" />
          <text-delete-button @click="handleDelete(row)" />
        </template>
      </el-table-column>
    </el-table>
    <pagination v-show="page.total > 0" :total="page.total" v-model:page="page.pageNum" v-model:limit="page.pageSize" @pagination="getCompList" />

    <drag-dialog title="组件设置" append-to-body v-model="showDialog" :close-on-click-modal="false" width="60%">
      <el-form :model="compForm" ref="form" :rules="compFormRules" label-position="left" label-width="125px" label-suffix=":">
        <el-form-item label="版本号" prop="version" v-if="dialogType !== 'add'">
          <el-input v-model="compForm.version" :disabled="true" />
        </el-form-item>
        <el-form-item label="组件标签" prop="label">
          <el-input v-model="compForm.label" placeholder="请输入组件标签" />
        </el-form-item>
        <el-form-item label="组件名称" prop="chineseDesc">
          <el-input v-model="compForm.chineseDesc" placeholder="请输入组件名称" />
        </el-form-item>
        <el-form-item label="前端值类型" prop="valueType">
          <el-select v-model="compForm.valueType" clearable >
            <el-option v-for="dict in valueTypeOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue"/>
          </el-select>
        </el-form-item>
        <el-form-item label="组件类别" prop="componentForm">
          <el-radio v-for="(option, index) in componentFormOptions" v-model="compForm.componentForm" :label="option.dictValue" :key="index">{{ option.dictLabel }}</el-radio>
        </el-form-item>
        <el-form-item label="组件JSON" prop="componentJson">
          <el-input type="textarea" :rows="6" v-model="compForm.componentJson" placeholder="请输入组件JSON" />
        </el-form-item>
        <el-form-item label="是否低代码组件" prop="isLowCode">
            <el-radio-group v-model="compForm.isLowCode">
              <el-radio v-for="dict in isEnableOptions" :key="dict.dictValue" :label="dict.dictValue">{{ dict.dictLabel }}</el-radio>
            </el-radio-group>
      </el-form-item>
      <el-form-item label="是否零代码组件" prop="isZeroCode">
            <el-radio-group v-model="compForm.isZeroCode">
              <el-radio v-for="dict in isEnableOptions" :key="dict.dictValue" :label="dict.dictValue">{{ dict.dictLabel }}</el-radio>
            </el-radio-group>
      </el-form-item>
        <el-form-item label="排序" prop="sort">
          <el-input v-model="compForm.sort" placeholder="请输入排序" />
        </el-form-item>
      </el-form>
      <template #footer>
        <dialog-footer @ok="addComp" @cancel="closeDialog" />
      </template>
    </drag-dialog>

    <drag-dialog title="组件Json" append-to-body v-model="jsonDialogParams.openJsonDialog" :close-on-click-modal="false" width="40%">
      <div style="max-height: 500px;">
        <pre style="white-space: pre-wrap;">{{ JSON.stringify(jsonDialogParams.componentJson, null, 2) }}</pre>
      </div>
      <template #footer>
        <dialog-footer :showOk="false" @cancel="closeJsonDialog" />
      </template>
    </drag-dialog>

    <drag-dialog
      :title="upload.title"
      :close-on-click-modal="false"
      v-model="upload.open"
      width="400px"
      append-to-body
    >
      <el-upload
        ref="upload"
        :limit="1"
        accept=".zip"
        :headers="upload.headers"
        :action="upload.url"
        :disabled="upload.isUploading"
        :on-progress="handleFileUploadProgress"
        :on-success="handleFileSuccess"
        :auto-upload="false"
        drag
      >
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">
          将文件拖到此处，或
          <em>点击上传</em>
        </div>
        <template #tip>
          <div class="el-upload__tip">
            Tips：导入导出主要用于多环境间数据传递，因此不建议用户对导出的包进行修改
            <div class="el-upload__tip" style="color: red">
              提示：仅允许上传“zip”格式文件！
            </div>
          </div>
        </template>
      </el-upload>
      <template #footer>
        <dialog-footer @ok="submitFileForm" @cancel="cancelUpload" />
      </template>
    </drag-dialog>
  </div>
</template>

<script>
import { insertComp, searchCompListByUser, updateComp, updateBatchComp, searchCompListByAll } from '@code/api/code/compbackend/index';
import {debounceWrapper} from "@/utils/zmids";
import defaultSettings from '@/settings'
import { getToken } from '@/utils/auth';

export default {
  name: 'CodeCompbackend',
  data() {
    return {
      // 模型状态的固定字典选项列表
      isEnableOptions: [
        { dictValue: 'Y', dictLabel: '是' },
        { dictValue: 'N', dictLabel: '否' }
      ],
      compForm: {
        version: 1, // 初始版本
        label: '',
        dataType: '',
        attributeLength: '',
        floatLength: '',
        chineseDesc: '',
        isApp: 'N',
        valueType: '',
        componentForm: 'B',
        componentJson: '',
        sort: '',
        openLevel: 'A',
        isLowCode: '',
        isZeroCode:''
      },
      compFormRules: {
        label: [
          { required: true, message: '请输入组件标签！', trigger: 'blur' }
        ],
        dataType: [
          { required: true, message: '请输入后端数据类型！', trigger: 'blur' }
        ],
        attributeLength: [
          { required: true, message: '请输入属性长度！', trigger: 'blur' }
        ],
        floatLength: [
          { required: true, message: '请输入浮点长度！', trigger: 'blur' }
        ],
        chineseDesc: [
          { required: true, message: '请输入组件名称！', trigger: 'blur' }
        ],
        isApp: [
          { required: true, message: '请选择是否小程序组件！', trigger: 'change' }
        ],
        valueType: [
          { required: true, message: '请输入前端值类型！', trigger: 'blur' }
        ],
        componentForm: [
          { required: true, message: '请选择组件类别！', trigger: 'change' }
        ],
        componentJson: [
          { required: true, message: '请输入组件json！', trigger: 'blur' }
        ],
        sort: [
          { required: true, message: '请输入排序序号！', trigger: 'blur' }
        ],
        openLevel: [
          { required: true, message: '请选择开放级别！', trigger: 'change' }
        ],
        isLowCode: [
          { required: true, message: '请选择是否低代码组件！', trigger: 'blur' }
        ],
        isZeroCode: [
          { required: true, message: '请选择是否零代码组件！', trigger: 'blur' }
        ],
      },
      showDialog: false,
      compList: [],
      isAppOptions: [
        {
          dictLabel: '是',
          dictValue: 'Y'
        },
        {
          dictLabel: '否',
          dictValue: 'N'
        }
      ],
      componentFormOptions: [],
      valueTypeOptions: [],
      openLevelOptions: [
        {
          dictLabel: '所有',
          dictValue: 'A'
        },
        {
          dictLabel: '订阅',
          dictValue: 'S'
        }
      ],
      dialogType: 'add',
      loading: false,
      page: {
        pageSize: 10,
        pageNum: 1,
        total: 0,
        pageSizes: [10, 20, 30, 50]
      },
      searchParams: {
        chineseDesc: '',
        label: '',
        componentForm: '',
        valueType: '',
        isLowCode:'',
        isZeroCode:''
      },
      jsonDialogParams: {
        openJsonDialog: false,
        componentJson: {}
      },
      componentIds: '',
      // 导入参数
      upload: {
        // 是否显示弹出层
        open: false,
        // 弹出层标题
        title: '',
        // 是否禁用上传
        isUploading: false,
        // 设置上传的请求头部
        headers: { [defaultSettings.tokenName]: 'Bearer ' + getToken() },
        // 上传的地址
        url: import.meta.env.VITE_APP_BASE_API + '/code/component/market/importZip'
      }
    };
  },
  created() {
    this.getCompList();
    this.getCompTypeDicts();
    this.getValueTypeDicts();
  },
  methods: {
    handleAddComp() {
      this.resetForm();
      this.showDialog = true;
      this.dialogType = 'add';
    },
    closeDialog() {
      this.resetForm();
      this.showDialog = false;
    },
    resetForm() {
      this.$refs.form.resetFields();
      this.compForm = {
        version: 1, // 初始版本
        label: '',
        dataType: '',
        attributeLength: '',
        floatLength: '',
        chineseDesc: '',
        isApp: 'N',
        valueType: '',
        componentForm: 'B',
        componentJson: '',
        sort: '',
        openLevel: 'A',
        isLowCode:'',
        isZeroCode:''
      };
    },
    addComp() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          if (this.dialogType === 'add') {
            insertComp(this.compForm).then((res) => {
              this.getCompList();
              this.closeDialog();
              this.msgSuccess('新增成功！');
            });
          } else {
            this.compForm.version = +this.compForm.version + 1;
            updateComp(this.compForm).then((res) => {
              this.getCompList();
              this.closeDialog();
              this.msgSuccess('更新成功！');
            });
          }
        }
      });
    },
    getCompList() {
      const params = {
        pageNum: this.page.pageNum,
        pageSize: this.page.pageSize,
        orderBy: 'SORT',
        sortDirect: 'ASC',
        ...this.searchParams
      };
      return searchCompListByAll(params).then((res) => {
        if (res) {
          const { data } = res;
          this.compList = data.list;
          this.page.total = data.total;
        }
      });
    },
    reset() {
      this.$refs.search.resetFields();
      this.getCompList();
    },
    handleUpdate(row) {
      this.showDialog = true;
      this.compForm = { ...row };
      this.dialogType = 'edit';
    },
    handleDelete(row) {
      const params = {
        ...row,
        isDelete: 'Y'
      };
      updateComp(params).then((res) => {
        this.getCompList();
        this.msgSuccess('删除成功！');
      });
    },
    getCompTypeDicts() {
      return this.getDicts('code_component_group').then((res) => {
        this.componentFormOptions = res.data;
      });
    },
    getValueTypeDicts() {
      return this.getDicts('front_end_value_type').then((res) => {
        this.valueTypeOptions = res.data;
      });
    },
    handleSelectionChange(val) {
      this.componentIds = val.map(v => v.componentId).join(",");
    },
    handleBatchDelete:debounceWrapper(function() {
      const params = {
        isDelete: 'Y',
        ids: this.componentIds
      };
      updateBatchComp(params).then((res) => {
        this.componentIds = '';
        this.getCompList();
        this.msgSuccess('删除成功！');
      });
    }),
    openJson(row) {
      this.jsonDialogParams.componentJson = JSON.parse(row.componentJson);
      this.jsonDialogParams.openJsonDialog = true;
    },
    closeJsonDialog(){
      this.jsonDialogParams.componentJson = {};
      this.jsonDialogParams.openJsonDialog = false;
    },
    handleExport:debounceWrapper(function() {
      if (this.componentIds) {
        this.$confirm('是否确认导出选中的数据项?', '警告', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.downloadUrl('/code/component/market/exportComp', { "ids": this.componentIds })
        })
      } else {
        this.$confirm('是否确认导出所有的数据项?', '警告', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          const componentIds = this.compList.map(c => c.componentId).join(',');
          this.downloadUrl('/code/component/market/exportComp', { "ids": componentIds })
        })
      }
    }),
    handleImport() {
      this.upload.title = '组件导入'
      this.upload.open = true
    },
    submitFileForm() {
      this.$refs.upload.submit();
    },
    // 取消上传
    cancelUpload() {
      this.upload.open = false;
      this.upload.isUploading = false;
      this.$refs.upload.clearFiles();
    },
    // 文件上传中处理
    handleFileUploadProgress(event, file, fileList) {
      this.upload.isUploading = true
    },
    // 文件上传成功处理
    handleFileSuccess: debounceWrapper(function (response, file, fileList) {
      this.upload.open = false
      this.upload.isUploading = false
      this.$refs.upload.clearFiles()
      this.$alert(response.msg, '导入结果', { dangerouslyUseHTMLString: true })
      this.getCompList()
    }),
  }
};
</script>

<style>
/* .page {
  float: right;
  margin-top: 10px;
} */
</style>
